package com.wm.blog_common.util;


import com.wm.blog_common.annotation.NotEmpty;
import com.wm.blog_common.annotation.NotEmptyIn;
import com.wm.blog_common.result.Result;
import com.wm.blog_common.util.excel.FieldReflectionUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/***
 * @ClassName: ObjectValidateUtil
 * @Description: 自定义反射字段校验工具类
 * @Author: 半卷流年
 * @Create_time: 2020-04-05
 */
@Slf4j
public class ObjectValidateUtil {

    private ObjectValidateUtil(){}

    /**
     * 字段校验
     * @param target
     * @return
     */
    public static Result<String> validate(Object target, List<String>... ignoreList){
        if(null == target){
            return Result.failure("字段为空,校验失败");
        }
        List<String> ignoreFieldList = new ArrayList<>();
        if(!ObjectUtils.isEmpty(ignoreList)){
            List<String> list = ignoreList[0];
            if(!CollectionUtils.isEmpty(list)){
                ignoreFieldList.addAll(list);
            }
        }
        Class<?> clzz = target.getClass();
        Field[] fields = FieldReflectionUtil.getAllFields(clzz);
        //过滤字段
        List<Field> list = Arrays.stream(fields)
                .filter((Field var) -> !Modifier.isStatic(var.getModifiers()) && !Modifier.isFinal(var.getModifiers()) && !ignoreFieldList.contains(var.getName()))
                .collect(Collectors.toList());
        for (Field field : list) {
            try {
                Result<String> response = doCheck(field, target,ignoreFieldList);
                if(!response.isSuccess()){
                    return response;
                }
            } catch (Exception e) {
                log.error("<autoCheck> check properties not empty error....{}" + e.getMessage(),e);
            }
        }
        return Result.success("success");

    }


    private static Result<String> doCheck(Field field,Object target,List<String> ignoreFieldList) throws Exception {
        if(field.isAnnotationPresent(NotEmpty.class)){
            Result response = autoMatch(field,target);
            if(!response.isSuccess()){
                return response;
            }
        }else if(field.isAnnotationPresent(NotEmptyIn.class)){
            if(!field.isAccessible()){
                field.setAccessible(true);
            }
            Result<String> response = deepToCheck(field, field.get(target),ignoreFieldList);
            if(!response.isSuccess()){
                return response;
            }
        }else{
            return Result.success("success");
        }
        return Result.success("success");
    }

    private static Result<String> deepToCheck(Field field,Object target,List<String> ignoreFieldList) throws Exception {
        if(null == target){
            return Result.failure("<deepToCheck> deep object .... " + field.toGenericString() + " cannot be null...{}");
        }
        if(field.isAnnotationPresent(NotEmptyIn.class)){
            //对有NotEmptyIn注解的字段层层深入,直到没有为止
            Class<?> clzz = field.getType().newInstance().getClass();
            Field[] fields = FieldReflectionUtil.getAllFields(clzz);
            //过滤字段
            List<Field> list = Arrays.stream(fields).filter((Field var) -> !Modifier.isStatic(var.getModifiers()) && !Modifier.isFinal(var.getModifiers()) && !ignoreFieldList.contains(var.getName())).collect(Collectors.toList());
            for (Field var : list) {
                if(var.isAnnotationPresent(NotEmpty.class)){
                    Result response = autoMatch(var,target);
                    if(!response.isSuccess()){
                        return response;
                    }
                }else if(var.isAnnotationPresent(NotEmptyIn.class)){
                    Class<? extends Class> c = var.getType().getClass();
                    //获取小对象的值
                    if(!var.isAccessible()){
                        var.setAccessible(true);
                    }
                    Object o = var.get(target);
                    //Field[] varFields = FeildReflectUtil.getAllFields(clzz);
                    List<Field> varList = Arrays.stream(fields).filter((Field var2) -> !Modifier.isStatic(var2.getModifiers()) && !Modifier.isFinal(var2.getModifiers())).collect(Collectors.toList());
                    //递归查找
                    for (Field var1 : varList) {
                        Result<String> response = deepToCheck(var1, o,ignoreFieldList);
                        if(!response.isSuccess()){
                            return response;
                        }
                    }
                }
            }
        }
        return Result.success("success");
    }


    /**
     * 自动匹配对应的类型,用来做相应的处理
     * @param
     * @return
     */
    private static Result autoMatch(Field field,Object target){
        if(null == target){
            return Result.failure(field.toGenericString() + "can not be null...");
        }
        //获取字段的类型的名称,在获取到对应的字节码(也就是类型的字节码对象)
        Class clzz = field.getType().getName().getClass();
        String value = field.getAnnotation(NotEmpty.class).value();
        Object o = null;
        try {
            if(!field.isAccessible()){
                field.setAccessible(true);
            }
            o = field.get(target);
        } catch (IllegalAccessException e) {
            log.error("<autoMatch> error....{}" + e.getMessage(),e);
        }
        if(o == null){
            return Result.failure(value);
        }
        if(String.class == clzz){
            if(StringUtils.isEmpty(o)){
                return Result.failure(value);
            }
        }
        return Result.success("success");
    }





}
